package cn.example.demo.modules.house.recommend.task;

import cn.example.demo.modules.house.dto.RecommendResultDto;
import cn.example.demo.modules.house.recommend.ConfigParam;
import cn.example.demo.modules.house.recommend.engine.ContentBasedRecommenderEngine;
import cn.example.demo.modules.house.service.IRecommendResultService;
import cn.example.demo.modules.sys.mapper.SysUserMapper;
import cn.example.demo.modules.sys.model.entity.SysUser;
import cn.hutool.json.JSONUtil;
import com.github.benmanes.caffeine.cache.Cache;
import lombok.extern.slf4j.Slf4j;
import org.apache.mahout.cf.taste.recommender.RecommendedItem;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.stream.Collectors;

/**
 * Description: 推荐结果生成任务（定时调度）
 *
 * @author Lzx
 * @create 2025/3/22 18:04
 */
@Component
@Slf4j
public class RecommendGenerationTask {
    @Autowired
    private SysUserMapper userMapper;
    @Autowired
    private ContentBasedRecommenderEngine contentBasedRecommenderEngine;
    @Autowired
    private IRecommendResultService recommendResultService;
    @Autowired
    private Cache<String, Object> dictCache;

    @Scheduled(cron = "0 */1 * * * *")
    public void generateDailyRecommend() {
        List<Integer> activeUserIds = userMapper.selectList(null).stream().map(SysUser::getUserId).collect(Collectors.toList());
        activeUserIds.parallelStream().forEach(userId -> {
            try {
                // TODO-lzx 基于内容的推荐，后期改混合推荐（结合协同过滤）
                List<RecommendedItem> items = contentBasedRecommenderEngine.recommend(userId, Integer.parseInt(dictCache.get(ConfigParam.RECOMMEND_LIST_NUM.getCode(), (o) -> 10).toString()));
                List<String> houseIds = items.stream()
                        .map(item -> String.valueOf(item.getItemID()))
                        .collect(Collectors.toList());
                if (houseIds.size() > 0) {
                    // 保存到推荐结果列表
                    recommendResultService.insertRecommendResult(new RecommendResultDto(userId, JSONUtil.toJsonStr(houseIds), "V1.0", "BasedContent"));
                }
            } catch (Exception e) {
                log.error("生成推荐失败: {}", userId, e);
            }
        });
    }
}
